/**
 * Created by Wang on 2018/7/16.
 */
if (console == null) {
    var console = {
        info: function () {
            var resultString = Array.prototype.slice.apply(arguments).join(',');
            Java.type("java.lang.System").out.println(resultString);
        }
    }
}

function isJavaType(o) {
    return o.getClass != null;
}

function isRawArray(list) {
    return Object.prototype.toString.call(list) == "[object Array]";
}

function isJavaArray(list) {
    return isJavaType(list) && list.getClass().isArray();
}

function isJavaList(list) {
    return isJavaType(list) && list instanceof Java.type("java.util.Collection");
}

function isList(list) {
    return isRawArray(list) || isJavaList(list) || isJavaArray(list);
}

function toRawArray(list) {
    if (isRawArray(list)) {
        return list;
    }
    if (isJavaList(list) || isJavaArray(list)) {
        return Java.from(list);
    }
}

function toJavaArray(list, type) {
    type = type || "Object[]";
    return Java.to(toRawArray(list), type)
}

function toJavaList(list) {
    return toJavaArray(list, "java.util.List");
}

(function () {
    var myContext = Java.type("cn.edu.hit.kg.ScriptContext").getInstance();
    myContext.registService('toRawArray', '1.0.0', toRawArray);

    function unbox(a) {
        if (isList(a)) {
            var list = toRawArray(a);
            return list.length > 0 ? a[0] : null;
        }
        return a;
    }

    myContext.registService('unbox', '1.0.0', unbox);
    myContext.registService('>', '1.0.0', function (a, b) {
        console.info(a, b);
        return unbox(a) > unbox(b);
    });

    myContext.registService('<', '1.0.0', function (a, b) {
        return unbox(a) < unbox(b);
    });

    function eq(a, b) {
        return unbox(a) == unbox(b);
    }

    myContext.registService('=', '1.0.0', eq);
    myContext.registService('==', '1.0.0', eq);
    myContext.registService('eq', '1.0.0', eq);
    myContext.registService('equal', '1.0.0', eq);

    myContext.registService('>=', '1.0.0', function (a, b) {
        return unbox(a) >= unbox(b);
    });

    myContext.registService('<=', '1.0.0', function (a, b) {
        return unbox(a) <= unbox(b);
    });

    function mapCall(list, func, thisArg) {
        list = toRawArray(list);
        return list.map(func, thisArg);
    }

    function reduceCall(list, func, initialValue) {
        list = toRawArray(list);
        return list.reduce(func, initialValue);
    }

    myContext.registService("map", "1.0.0", mapCall);
    myContext.registService("reduce", "1.0.0", reduceCall);

    myContext.registService("max", "1.0.0", function (list, comparetor) {
        list = toRawArray(list);
        comparetor = comparetor ||
            function (x, y) {
                return Java.type("java.lang.Math").signum(x - y);
            };
        var result = list.reduce(function (x, y) {
            return comparetor(x, y) < 0 ? y : x;
        });
        //console.info("Max Value:"+result);
        return result;
    });

    myContext.registService("min", "1.0.0", function (list, compatetor) {
        list = toRawArray(list);
        compatetor = compatetor ||
            function (x, y) {
                return Java.type("java.lang.Math").signum(x - y);
            };
        var result = list.reduce(function (x, y) {
            return compatetor(x, y) > 0 ? y : x;
        });
        //console.info("Min Value:"+result);
        return result;
    });

    myContext.registService("sum", "1.0.0", function (list) {
        list = toRawArray(list);
        return list.reduce(function (x, y) {
            return x + y;
        });
    });


})();
